diff --git a/smart-switch-ruoyi/smart-switch-common/src/main/java/com/ruoyi/common/constant/IotConstants.java b/smart-switch-ruoyi/smart-switch-common/src/main/java/com/ruoyi/common/constant/IotConstants.java
index 37ddd1ff..92b69363 100644
--- a/smart-switch-ruoyi/smart-switch-common/src/main/java/com/ruoyi/common/constant/IotConstants.java
+++ b/smart-switch-ruoyi/smart-switch-common/src/main/java/com/ruoyi/common/constant/IotConstants.java
@@ -60,7 +60,7 @@ public class IotConstants {
     /**
      * 命令  电量充值
      */
-    public static final String COMMAND_RECHARGE = "money";
+    public static final String COMMAND_RECHARGE = "time";
 
     /**
      * 命令  设置断电方式
@@ -69,5 +69,4 @@ public class IotConstants {
 
     /**----------------------------命令end----------------------------*/
 
-
 }
diff --git a/smart-switch-ruoyi/smart-switch-common/src/main/java/com/ruoyi/common/utils/NumberUtils.java b/smart-switch-ruoyi/smart-switch-common/src/main/java/com/ruoyi/common/utils/NumberUtils.java
index 1ebf875d..1f892c60 100644
--- a/smart-switch-ruoyi/smart-switch-common/src/main/java/com/ruoyi/common/utils/NumberUtils.java
+++ b/smart-switch-ruoyi/smart-switch-common/src/main/java/com/ruoyi/common/utils/NumberUtils.java
@@ -27,7 +27,11 @@ public class NumberUtils {
         if (StringUtils.isBlank(value)) {
             return defaultValue;
         }
-        return new BigDecimal(value);
+        try {
+            return new BigDecimal(value);
+        } catch (Exception e) {
+            return defaultValue;
+        }
     }
 
     /**
@@ -40,7 +44,11 @@ public class NumberUtils {
         if (StringUtils.isBlank(value)) {
             return defaultValue;
         }
-        return Integer.parseInt(value);
+        try {
+            return Integer.parseInt(value);
+        } catch (Exception e) {
+            return defaultValue;
+        }
     }
 
     public static int nonNullInt(String value) {
diff --git a/smart-switch-service/src/main/java/com/ruoyi/iot/constants/ReceiveConstants.java b/smart-switch-service/src/main/java/com/ruoyi/iot/constants/ReceiveConstants.java
index 1f45c4f6..742b43b9 100644
--- a/smart-switch-service/src/main/java/com/ruoyi/iot/constants/ReceiveConstants.java
+++ b/smart-switch-service/src/main/java/com/ruoyi/iot/constants/ReceiveConstants.java
@@ -8,8 +8,24 @@ public class ReceiveConstants {
 
     // 数据点ID:SSID
     public static final String DS_SSID = "ssid";
+    // 数据点ID:电压
+    public static final String DS_V = "V";
+    // 数据点ID:电流
+    public static final String DS_A = "A";
+    // 数据点ID:功率
+    public static final String DS_P = "P";
+    // 数据点ID:总电量
+    public static final String DS_W = "W";
+    // 数据点ID:开关状态
+    public static final String DS_S = "S";
+    // 数据点ID:剩余金额
+    public static final String DS_M = "M";
+    // 数据点ID:断电方式
+    public static final String DS_SET = "SET";
+    // 数据点ID:剩余时长(秒)
+    public static final String DS_TIME = "TIME";
 
     // 数据点ID:SSID的值:创特
-    public static final String DSV_SSID_CT = "ChangteA";
+    public static final String DSV_SSID_CT = "ChuangteA";
 
 }
diff --git a/smart-switch-service/src/main/java/com/ruoyi/iot/domain/CurrentDeviceData.java b/smart-switch-service/src/main/java/com/ruoyi/iot/domain/CurrentDeviceData.java
index 721afec3..c259ca5a 100644
--- a/smart-switch-service/src/main/java/com/ruoyi/iot/domain/CurrentDeviceData.java
+++ b/smart-switch-service/src/main/java/com/ruoyi/iot/domain/CurrentDeviceData.java
@@ -1,5 +1,6 @@
 package com.ruoyi.iot.domain;
 
+import com.ruoyi.common.constant.IotConstants;
 import com.ruoyi.common.utils.NumberUtils;
 import com.ruoyi.ss.device.domain.enums.DeviceOutageWay;
 import lombok.Data;
@@ -58,6 +59,9 @@ public class CurrentDeviceData {
                     DeviceOutageWay deviceOutageWay = DeviceOutageWay.parse(value);
                     device.setSet(deviceOutageWay.getValue());
                     break;
+                case "TIME":
+                    device.setTime(NumberUtils.nonNullDecimal(value));
+                    break;
                 default:
                     break;
             }
diff --git a/smart-switch-service/src/main/java/com/ruoyi/iot/domain/IotDeviceInfo.java b/smart-switch-service/src/main/java/com/ruoyi/iot/domain/IotDeviceInfo.java
index 7b508730..ca3636b2 100644
--- a/smart-switch-service/src/main/java/com/ruoyi/iot/domain/IotDeviceInfo.java
+++ b/smart-switch-service/src/main/java/com/ruoyi/iot/domain/IotDeviceInfo.java
@@ -30,6 +30,7 @@ public class IotDeviceInfo {
     private String s;   // 开关状态,0不通电,1闭合通电
     private BigDecimal m;   // 剩余电量(度)
     private String set; // 欠费断电方式
+    private BigDecimal time;   // 剩余时间(秒)
 
     public static IotDeviceInfo newDefaultInstance() {
         return IotDeviceInfo.builder()
@@ -40,6 +41,7 @@ public class IotDeviceInfo {
                 .s("0")
                 .m(BigDecimal.ZERO)
                 .set(DeviceOutageWay.IMMEDIATE.getValue())
+                .time(BigDecimal.ZERO)
                 .build();
     }
 
diff --git a/smart-switch-service/src/main/java/com/ruoyi/iot/service/IotReceiveServiceImpl.java b/smart-switch-service/src/main/java/com/ruoyi/iot/service/IotReceiveServiceImpl.java
index 13af1775..8fce9cca 100644
--- a/smart-switch-service/src/main/java/com/ruoyi/iot/service/IotReceiveServiceImpl.java
+++ b/smart-switch-service/src/main/java/com/ruoyi/iot/service/IotReceiveServiceImpl.java
@@ -1,13 +1,20 @@
 package com.ruoyi.iot.service;
+import com.ruoyi.common.constant.IotConstants;
+import com.ruoyi.common.utils.NumberUtils;
+import com.ruoyi.common.utils.StringUtils;
 import com.ruoyi.iot.constants.ReceiveConstants;
 import com.ruoyi.iot.domain.ReceiveMsg;
 import com.ruoyi.iot.enums.ReceiveType;
 import com.ruoyi.ss.device.domain.SmDevice;
+import com.ruoyi.ss.device.domain.enums.DeviceOutageWay;
 import com.ruoyi.ss.device.service.ISmDeviceService;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+
 /**
  * @author wjh
  * 2024/5/6
@@ -23,17 +30,55 @@ public class IotReceiveServiceImpl implements IotReceiveService{
     public void handleReceive(ReceiveMsg msg) {
         log.info("handleReceive {}", msg.toString());
         if (ReceiveType.DATA_POINT.getType().equals(msg.getType())
-                && ReceiveConstants.DS_SSID.equals(msg.getDsId())
-                && ReceiveConstants.DSV_SSID_CT.equals((String) msg.getValue())
         ) {
-            // 当数据点推送ssid的值为ChangteA时,录入设备
-            deviceService.addInitDevice(this.parseToDevice(msg));
+            if (ReceiveConstants.DS_SSID.equals(msg.getDsId())
+                    && ReceiveConstants.DSV_SSID_CT.equals((String) msg.getValue())) {
+                // 当数据点推送ssid的值为ChangteA时,录入设备
+                deviceService.addInitDevice(this.parseToDevice(msg));
+            } else {
+                // 其他情况,更新设备信息
+                deviceService.updateByIot(this.parseToDevice(msg));
+            }
         }
     }
 
     private SmDevice parseToDevice(ReceiveMsg msg) {
         SmDevice device = new SmDevice();
         device.setMac(msg.getDevName());
+
+        if (StringUtils.hasText(msg.getDsId())) {
+            String value = msg.getValue().toString();
+            switch(msg.getDsId()) {
+                case ReceiveConstants.DS_SSID:
+                    device.setWifi(value);
+                    break;
+                case ReceiveConstants.DS_V:
+                    device.setVoltage(NumberUtils.nonNullDecimal(value));
+                    break;
+                case ReceiveConstants.DS_P:
+                    device.setRealTimePower(NumberUtils.nonNullDecimal(value));
+                    break;
+                case ReceiveConstants.DS_A:
+                    device.setElectricity(NumberUtils.nonNullDecimal(value));
+                    break;
+                case ReceiveConstants.DS_W:
+                    device.setTotalElectriQuantity(NumberUtils.nonNullDecimal(value).divide(new BigDecimal(1000), 2, RoundingMode.HALF_UP));
+                    break;
+                case ReceiveConstants.DS_S:
+                    device.setPowerStatus(value);
+                    break;
+                case ReceiveConstants.DS_SET:
+                    DeviceOutageWay deviceOutageWay = DeviceOutageWay.parse(value);
+                    device.setOutageWay(deviceOutageWay.getValue());
+                    break;
+                case ReceiveConstants.DS_TIME:
+                    device.setRemainTime(NumberUtils.nonNullDecimal(value));
+                    break;
+                default:
+                    break;
+            }
+        }
+
         return device;
     }
 
diff --git a/smart-switch-service/src/main/java/com/ruoyi/iot/service/IotServiceImpl.java b/smart-switch-service/src/main/java/com/ruoyi/iot/service/IotServiceImpl.java
index 0e203e6c..474f7790 100644
--- a/smart-switch-service/src/main/java/com/ruoyi/iot/service/IotServiceImpl.java
+++ b/smart-switch-service/src/main/java/com/ruoyi/iot/service/IotServiceImpl.java
@@ -180,7 +180,7 @@ public class IotServiceImpl implements IotService {
             log.error("充值设备参数错误:读数不允许为空或者小于0");
             return false;
         }
-        CommandResponse response = sendCommand(deviceName, IotConstants.COMMAND_RECHARGE + num.multiply(new BigDecimal(1000)) + IotConstants.COMMAND_SEPARATOR);
+        CommandResponse response = sendCommand(deviceName, IotConstants.COMMAND_RECHARGE + num.multiply(new BigDecimal(60)) + IotConstants.COMMAND_SEPARATOR);
         if (!Objects.equals(HttpStatus.IOT_SUCCESS, response.getCode())) {
             log.error("充值设备发生异常:" + response.getMsg());
             return false;
diff --git a/smart-switch-service/src/main/java/com/ruoyi/ss/device/domain/SmDevice.java b/smart-switch-service/src/main/java/com/ruoyi/ss/device/domain/SmDevice.java
index 65ded40c..7b4b3d1a 100644
--- a/smart-switch-service/src/main/java/com/ruoyi/ss/device/domain/SmDevice.java
+++ b/smart-switch-service/src/main/java/com/ruoyi/ss/device/domain/SmDevice.java
@@ -139,10 +139,6 @@ public class SmDevice extends BaseEntity
     @JsonView(DeviceView.SuitList.class)
     private LocalDateTime expireTime;
 
-    @ApiModelProperty("所属用户ID")
-    @NotNull(message = "用户不允许为空", groups = {ValidGroup.Create.class})
-    private Long userId;
-
     @ApiModelProperty("用户自定义图片")
     private String customPicture;
 
@@ -150,4 +146,6 @@ public class SmDevice extends BaseEntity
     @Range(min = 0, max = 100, message = "服务费费率必须在0-100之间")
     private BigDecimal serviceRate;
 
+    @ApiModelProperty("剩余时长(秒)")
+    private BigDecimal remainTime;
 }
diff --git a/smart-switch-service/src/main/java/com/ruoyi/ss/device/domain/SmDeviceBO.java b/smart-switch-service/src/main/java/com/ruoyi/ss/device/domain/SmDeviceBO.java
index 581f14c1..be74c5c4 100644
--- a/smart-switch-service/src/main/java/com/ruoyi/ss/device/domain/SmDeviceBO.java
+++ b/smart-switch-service/src/main/java/com/ruoyi/ss/device/domain/SmDeviceBO.java
@@ -19,7 +19,6 @@ public class SmDeviceBO extends SmDevice {
         bo.setDeviceName(getDeviceName());
         bo.setModelId(getModelId());
         bo.setMac(getMac());
-        bo.setUserId(getUserId());
         bo.setServiceRate(getServiceRate());
         return bo;
     }
@@ -34,7 +33,6 @@ public class SmDeviceBO extends SmDevice {
         bo.setStoreId(getStoreId());
         bo.setDeviceName(getDeviceName());
         bo.setModelId(getModelId());
-        bo.setUserId(getUserId());
         bo.setServiceRate(getServiceRate());
         return bo;
     }
diff --git a/smart-switch-service/src/main/java/com/ruoyi/ss/device/domain/SmDeviceQuery.java b/smart-switch-service/src/main/java/com/ruoyi/ss/device/domain/SmDeviceQuery.java
index 488cd15f..64420eaf 100644
--- a/smart-switch-service/src/main/java/com/ruoyi/ss/device/domain/SmDeviceQuery.java
+++ b/smart-switch-service/src/main/java/com/ruoyi/ss/device/domain/SmDeviceQuery.java
@@ -1,11 +1,13 @@
 package com.ruoyi.ss.device.domain;
 
+import com.ruoyi.common.core.domain.ValidGroup;
 import com.ruoyi.common.valid.EnumValid;
 import com.ruoyi.ss.device.domain.enums.DeviceGroupBy;
 import com.ruoyi.ss.device.domain.enums.DeviceGroupByTable;
 import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
 
+import javax.validation.constraints.NotNull;
 import java.util.List;
 
 /**
@@ -18,6 +20,9 @@ public class SmDeviceQuery extends SmDevice {
     @ApiModelProperty("设备id列表")
     private List<Long> deviceIds;
 
+    @ApiModelProperty("所属用户ID")
+    private Long userId;
+
     @ApiModelProperty("型号列表")
     private List<Long> modelIds;
 
diff --git a/smart-switch-service/src/main/java/com/ruoyi/ss/device/domain/vo/SmDeviceVo.java b/smart-switch-service/src/main/java/com/ruoyi/ss/device/domain/vo/SmDeviceVo.java
index 52546a21..d361076b 100644
--- a/smart-switch-service/src/main/java/com/ruoyi/ss/device/domain/vo/SmDeviceVo.java
+++ b/smart-switch-service/src/main/java/com/ruoyi/ss/device/domain/vo/SmDeviceVo.java
@@ -3,12 +3,14 @@ package com.ruoyi.ss.device.domain.vo;
 import com.fasterxml.jackson.annotation.JsonFormat;
 import com.fasterxml.jackson.annotation.JsonView;
 import com.ruoyi.common.core.domain.JsonViewProfile;
+import com.ruoyi.common.core.domain.ValidGroup;
 import com.ruoyi.ss.device.domain.DeviceView;
 import com.ruoyi.ss.device.domain.SmDevice;
 import com.ruoyi.ss.suit.domain.SuitVo;
 import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
 
+import javax.validation.constraints.NotNull;
 import java.math.BigDecimal;
 import java.time.LocalTime;
 import java.util.List;
@@ -22,6 +24,10 @@ public class SmDeviceVo extends SmDevice {
     @ApiModelProperty("是否默认")
     private Boolean isDefault;    // 是否默认
 
+    @ApiModelProperty("所属用户ID")
+    @NotNull(message = "用户不允许为空", groups = {ValidGroup.Create.class})
+    private Long userId;
+
     @ApiModelProperty("租户id列表")
     private List<Long> tenantIds;   // 租户id列表
 
diff --git a/smart-switch-service/src/main/java/com/ruoyi/ss/device/mapper/SmDeviceMapper.java b/smart-switch-service/src/main/java/com/ruoyi/ss/device/mapper/SmDeviceMapper.java
index 3e09cb4d..d7dc8b6b 100644
--- a/smart-switch-service/src/main/java/com/ruoyi/ss/device/mapper/SmDeviceMapper.java
+++ b/smart-switch-service/src/main/java/com/ruoyi/ss/device/mapper/SmDeviceMapper.java
@@ -144,5 +144,16 @@ public interface SmDeviceMapper
     /**
      * 通过用户id修改服务费率
      */
-    int updateServiceRateByUserId(@Param("userId") Long userId, @Param("serviceRate") BigDecimal serviceRate);
+    int updateServiceRateByStores(@Param("storeIds") List<Long> storeIds, @Param("serviceRate") BigDecimal serviceRate);
+
+    /**
+     * 根据MAC修改数据
+     * @param smDevice
+     */
+    int updateSmDeviceByIot(SmDevice smDevice);
+
+    /**
+     * 设备超时修改状态
+     */
+    int changeTimeoutStatus(@Param("deviceId") Long deviceId);
 }
diff --git a/smart-switch-service/src/main/java/com/ruoyi/ss/device/mapper/SmDeviceMapper.xml b/smart-switch-service/src/main/java/com/ruoyi/ss/device/mapper/SmDeviceMapper.xml
index f8f38389..f833e126 100644
--- a/smart-switch-service/src/main/java/com/ruoyi/ss/device/mapper/SmDeviceMapper.xml
+++ b/smart-switch-service/src/main/java/com/ruoyi/ss/device/mapper/SmDeviceMapper.xml
@@ -19,7 +19,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         <if test="status != null  and status != ''"> and sd.status = #{status}</if>
         <if test="userName != null  and userName != ''"> and su.user_name like concat('%', #{userName}, '%')</if>
         <if test="nickName != null  and nickName != ''"> and sd.nick_name like concat('%', #{nickName}, '%')</if>
-        <if test="userId != null"> and sd.user_id = #{userId}</if>
+        <if test="userId != null"> and ss.user_id = #{userId}</if>
         <if test="storeId != null"> and sd.store_id = #{storeId}</if>
         <if test="deviceId != null"> and sd.device_id = #{deviceId}</if>
         <if test="deviceNo != null"> and sd.device_no like concat('%', #{deviceNo}, '%')</if>
@@ -50,7 +50,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             </foreach>
         </if>
         <if test="userIds != null and userIds.size() > 0">
-            and sd.user_id in
+            and ss.user_id in
             <foreach collection="userIds" open="(" close=")" separator="," item="item">
                 #{item}
             </foreach>
@@ -70,7 +70,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         from sm_device sd
             left join sm_model sm on sm.model_id = sd.model_id
             left join sm_store ss on ss.store_id = sd.store_id
-            left join sm_user su on su.user_id = sd.user_id
+            left join sm_user su on su.user_id = ss.user_id
     </sql>
 
     <select id="selectSmDeviceList" parameterType="SmDeviceQuery" resultMap="SmDeviceResult">
@@ -193,9 +193,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="initReading != null">init_reading,</if>
             <if test="powerStatus != null">power_status,</if>
             <if test="deviceNo != null">device_no,</if>
-            <if test="userId != null">user_id,</if>
             <if test="customPicture != null">custom_picture,</if>
             <if test="serviceRate != null">service_rate,</if>
+            <if test="remainTime != null">remain_time,</if>
          </trim>
         <trim prefix="values (" suffix=")" suffixOverrides=",">
             <if test="storeId != null">#{storeId},</if>
@@ -222,9 +222,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="initReading != null">#{initReading},</if>
             <if test="powerStatus != null">#{powerStatus},</if>
             <if test="deviceNo != null">#{deviceNo},</if>
-            <if test="userId != null">#{userId},</if>
             <if test="customPicture != null">#{customPicture},</if>
             <if test="serviceRate != null">#{serviceRate},</if>
+            <if test="remainTime != null">#{remainTime},</if>
          </trim>
     </insert>
 
@@ -272,9 +272,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="initReading != null">init_reading = #{initReading},</if>
             <if test="powerStatus != null">power_status = #{powerStatus},</if>
             <if test="expireTime != null">expire_time = #{expireTime},</if>
-            <if test="userId != null">user_id = #{userId},</if>
             <if test="customPicture != null">custom_picture = #{customPicture},</if>
             <if test="serviceRate != null">service_rate = #{serviceRate},</if>
+            <if test="remainTime != null">remain_time = #{remainTime},</if>
         </trim>
         where device_id = #{deviceId}
     </update>
@@ -301,10 +301,39 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         where device_id = #{deviceId}
     </update>
 
-    <update id="updateServiceRateByUserId">
+    <update id="updateServiceRateByStores">
         update sm_device
         set service_rate = #{serviceRate}
-        where user_id = #{userId}
+        where store_id in
+        <foreach collection="storeIds" separator="," open="(" item="item" close=")">
+            #{item}
+        </foreach>
+    </update>
+
+    <update id="updateSmDeviceByIot">
+        update sm_device
+        <trim prefix="SET" suffixOverrides=",">
+            <if test="totalElectriQuantity != null">total_electri_quantity = #{totalElectriQuantity},</if>
+            <if test="onlineStatus != null">online_status = #{onlineStatus},</if>
+            <if test="realTimePower != null">real_time_power = #{realTimePower},</if>
+            <if test="electricity != null">electricity = #{electricity},</if>
+            <if test="voltage != null">voltage = #{voltage},</if>
+            <if test="outageWay != null">outage_way = #{outageWay},</if>
+            <if test="wifi != null">wifi = #{wifi},</if>
+            <if test="lastPullTime != null">last_pull_time = #{lastPullTime},</if>
+            <if test="powerStatus != null">power_status = #{powerStatus},</if>
+            <if test="remainTime != null">remain_time = #{remainTime},</if>
+        </trim>
+        where mac = #{mac}
+    </update>
+
+    <update id="changeTimeoutStatus">
+        update sm_device
+        set status = '1'
+        where expire_time &lt;= now()
+        <if test="deviceId != null">
+            and device_id = #{deviceId}
+        </if>
     </update>
 
     <delete id="deleteSmDeviceByDeviceId" parameterType="Long">
diff --git a/smart-switch-service/src/main/java/com/ruoyi/ss/device/service/ISmDeviceService.java b/smart-switch-service/src/main/java/com/ruoyi/ss/device/service/ISmDeviceService.java
index 7a78900a..4e95b961 100644
--- a/smart-switch-service/src/main/java/com/ruoyi/ss/device/service/ISmDeviceService.java
+++ b/smart-switch-service/src/main/java/com/ruoyi/ss/device/service/ISmDeviceService.java
@@ -104,13 +104,16 @@ public interface ISmDeviceService
     void pullDeviceInfo(List<Long> deviceIds);
 
     /**
-     * 通过mac绑定设备
-     * 设备第一次绑定为商户
-     * 其他时候绑定为租户
+     * 通过SN绑定设备
      * @param storeId 店铺ID
      * @param deviceNo 设备编号(SN)
      */
-    boolean bind(Long storeId, String deviceNo);
+    boolean bindBySn(Long storeId, String deviceNo);
+
+    /**
+     * 通过MAC绑定设备
+     */
+    boolean bindByMac(Long storeId, String mac);
 
     /**
      * 商户解绑设备
@@ -192,4 +195,14 @@ public interface ISmDeviceService
      * 更新设备服务费
      */
     int updateServiceRateByUserId(Long userId, BigDecimal serviceRate);
+
+    /**
+     * 更新设备信息
+     */
+    int updateByIot(SmDevice smDevice);
+
+    /**
+     * 刷新设备状态,如果过期,则修改为正常
+     */
+    void freshStatus(SmDeviceVo device);
 }
diff --git a/smart-switch-service/src/main/java/com/ruoyi/ss/device/service/impl/DeviceValidatorImpl.java b/smart-switch-service/src/main/java/com/ruoyi/ss/device/service/impl/DeviceValidatorImpl.java
index 5ac9e0be..1496fd14 100644
--- a/smart-switch-service/src/main/java/com/ruoyi/ss/device/service/impl/DeviceValidatorImpl.java
+++ b/smart-switch-service/src/main/java/com/ruoyi/ss/device/service/impl/DeviceValidatorImpl.java
@@ -81,14 +81,6 @@ public class DeviceValidatorImpl extends BaseValidator implements DeviceValidato
             return error("店铺不存在");
         }
 
-        if (!userValidator.isExist(Collections.singletonList(data.getUserId()))) {
-            return error("用户不存在");
-        }
-
-        if (data.getStoreId() != null && !storeValidator.isStoreBelongUser(Collections.singletonList(data.getStoreId()), data.getUserId())) {
-            return error("该店铺不属于该用户");
-        }
-
         return success();
     }
 
@@ -107,14 +99,6 @@ public class DeviceValidatorImpl extends BaseValidator implements DeviceValidato
             return error("店铺不存在");
         }
 
-        if (data.getUserId() != null && !userValidator.isExist(Collections.singletonList(data.getUserId()))) {
-            return error("用户不存在");
-        }
-
-        if (data.getStoreId() != null && !storeValidator.isStoreBelongUser(Collections.singletonList(data.getStoreId()), data.getUserId())) {
-            return error("该店铺不属于该用户");
-        }
-
         return success();
     }
 
diff --git a/smart-switch-service/src/main/java/com/ruoyi/ss/device/service/impl/SmDeviceServiceImpl.java b/smart-switch-service/src/main/java/com/ruoyi/ss/device/service/impl/SmDeviceServiceImpl.java
index 624ca57d..1ff83239 100644
--- a/smart-switch-service/src/main/java/com/ruoyi/ss/device/service/impl/SmDeviceServiceImpl.java
+++ b/smart-switch-service/src/main/java/com/ruoyi/ss/device/service/impl/SmDeviceServiceImpl.java
@@ -25,13 +25,13 @@ import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Service;
-import org.springframework.transaction.annotation.Propagation;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.transaction.support.TransactionTemplate;
 
 import java.math.BigDecimal;
 import java.time.Duration;
 import java.time.LocalDateTime;
+import java.time.temporal.ChronoUnit;
 import java.util.*;
 import java.util.concurrent.ScheduledExecutorService;
 import java.util.concurrent.TimeUnit;
@@ -137,6 +137,7 @@ public class SmDeviceServiceImpl implements ISmDeviceService
                     device.setVoltage(deviceInfo.getV());
                     device.setRealTimePower(deviceInfo.getP());
                     device.setTotalElectriQuantity(deviceInfo.getW());  // 电量
+                    device.setRemainTime(deviceInfo.getTime());
                 }
             } else {
                 device.setOnlineStatus(DeviceOnlineStatus.OFFLINE.getStatus());
@@ -261,7 +262,6 @@ public class SmDeviceServiceImpl implements ISmDeviceService
     }
 
     @Override
-    @Transactional(propagation = Propagation.REQUIRES_NEW)
     public boolean addTime(Long deviceId, BigDecimal num) {
         ServiceUtil.assertion(num.compareTo(BigDecimal.ZERO) < 0, "增加的时长不允许小于0");
 
@@ -270,21 +270,61 @@ public class SmDeviceServiceImpl implements ISmDeviceService
         ServiceUtil.assertion(!StringUtils.hasText(device.getMac()), "设备MAC号为空");
         ServiceUtil.assertion(DeviceStatus.FIXING.getStatus().equals(device.getStatus()), "设备正在维修中,无法使用");
 
-        // 更新数据库时长
-        int updateCount = smDeviceMapper.addTime(deviceId, num);
-        ServiceUtil.assertion(updateCount != 1, "增加时长失败,请刷新后重试");
+        Boolean result = transactionTemplate.execute(status -> {
+            // 更新数据库时长
+            int updateCount = smDeviceMapper.addTime(deviceId, num);
+            ServiceUtil.assertion(updateCount != 1, "增加时长失败,请刷新后重试");
 
-        // 修改状态为使用中
-        changeStatus(deviceId, DeviceStatus.USING);
+            // 修改状态为使用中
+            changeStatus(deviceId, DeviceStatus.USING);
 
-        // 物联网设备增加时长
-        boolean rechargeResult = iotService.recharge(device.getMac(), num);
-        ServiceUtil.assertion(!rechargeResult, "设备充值失败");
+            // 物联网设备增加时长
+            boolean rechargeResult = iotService.recharge(device.getMac(), num);
+            ServiceUtil.assertion(!rechargeResult, "设备充值失败");
+
+            return Boolean.TRUE;
+        });
 
         // 拉取设备信息
-        this.pullDeviceInfoAsync(Collections.singletonList(deviceId), 3, TimeUnit.SECONDS);
+        if (result != null && result) {
+            this.pullDeviceInfoAsync(Collections.singletonList(deviceId), 3, TimeUnit.SECONDS);
 
-        return true;
+            // 时长结束后修改设备状态
+            scheduledExecutorService.schedule(()-> {
+                freshStatus(deviceId);
+            }, num.intValue(), TimeUnit.MINUTES);
+        }
+
+        return result != null && result;
+    }
+
+    private void freshStatus(Long deviceId) {
+        SmDeviceVo device = smDeviceMapper.selectSmDeviceByDeviceId(deviceId);
+        freshStatus(device);
+    }
+
+    @Override
+    public void freshStatus(SmDeviceVo device) {
+        if (device == null) {
+            return;
+        }
+        if (!DeviceStatus.USING.getStatus().equals(device.getStatus())) {
+            return;
+        }
+        LocalDateTime now = LocalDateTime.now();
+
+        // 如果已过期,则调整设备为正常状态
+        if (device.getExpireTime().isBefore(now) || device.getExpireTime().isEqual(now)) {
+            int i = smDeviceMapper.changeTimeoutStatus(device.getDeviceId());
+            if (i == 1) {
+                return;
+            }
+        }
+
+        // 如果没有过期,则延迟至过期时间继续查询
+        scheduledExecutorService.schedule(() -> {
+            freshStatus(device.getDeviceId());
+        }, device.getExpireTime().until(LocalDateTime.now(), ChronoUnit.MINUTES), TimeUnit.MINUTES);
     }
 
     private int changeStatus(Long deviceId, DeviceStatus status) {
@@ -394,6 +434,7 @@ public class SmDeviceServiceImpl implements ISmDeviceService
                     data.setLastPullTime(deviceInfo.getAt());
                     data.setTotalElectriQuantity(deviceInfo.getW());
                     data.setPowerStatus(deviceInfo.getS());
+                    data.setRemainTime(deviceInfo.getTime());
                 }
 
                 // 是否在线
@@ -420,11 +461,22 @@ public class SmDeviceServiceImpl implements ISmDeviceService
         }, delay, unit);
     }
 
+
+
     @Override
     @Transactional
-    public boolean bind(Long storeId, String deviceNo) {
-        // 判断设备是否存在
+    public boolean bindBySn(Long storeId, String deviceNo) {
         SmDeviceVo device = selectByDeviceNo(deviceNo);
+        return this.bind(storeId, device);
+    }
+
+    @Override
+    public boolean bindByMac(Long storeId, String mac) {
+        SmDeviceVo device = selectByMac(mac);
+        return this.bind(storeId, device);
+    }
+
+    private boolean bind(Long storeId, SmDeviceVo device) {
         ServiceUtil.assertion(device == null, "设备未录入");
         ServiceUtil.assertion(device.getStoreId() != null, "该设备已被绑定");
 
@@ -538,7 +590,18 @@ public class SmDeviceServiceImpl implements ISmDeviceService
         if (userId == null) {
             return 0;
         }
-        return smDeviceMapper.updateServiceRateByUserId(userId, serviceRate);
+        List<StoreVo> list = storeService.selectByUserId(userId);
+        if (CollectionUtils.isEmpty(list)) {
+            return 0;
+        }
+        return smDeviceMapper.updateServiceRateByStores(list.stream().map(StoreVo::getStoreId).collect(Collectors.toList()), serviceRate);
+    }
+
+    @Override
+    public int updateByIot(SmDevice smDevice) {
+        smDevice.setLastPullTime(DateUtils.getNowDate());
+        smDevice.setOnlineStatus(smDevice.getOnlineStatus());
+        return smDeviceMapper.updateSmDeviceByIot(smDevice);
     }
 
     /**
diff --git a/smart-switch-service/src/main/java/com/ruoyi/ss/store/mapper/StoreMapper.java b/smart-switch-service/src/main/java/com/ruoyi/ss/store/mapper/StoreMapper.java
index d08230b0..795cbca8 100644
--- a/smart-switch-service/src/main/java/com/ruoyi/ss/store/mapper/StoreMapper.java
+++ b/smart-switch-service/src/main/java/com/ruoyi/ss/store/mapper/StoreMapper.java
@@ -30,7 +30,7 @@ public interface StoreMapper
      * @param store 商户
      * @return 商户集合
      */
-    public List<StoreVo> selectSmStoreList(Store store);
+    public List<StoreVo> selectSmStoreList(StoreQuery store);
 
     /**
      * 新增商户
diff --git a/smart-switch-service/src/main/java/com/ruoyi/ss/store/service/IStoreService.java b/smart-switch-service/src/main/java/com/ruoyi/ss/store/service/IStoreService.java
index e493b3aa..2c5f748d 100644
--- a/smart-switch-service/src/main/java/com/ruoyi/ss/store/service/IStoreService.java
+++ b/smart-switch-service/src/main/java/com/ruoyi/ss/store/service/IStoreService.java
@@ -117,4 +117,9 @@ public interface IStoreService
      * ids查询列表
      */
     List<StoreVo> selectSmStoreListByIds(List<Long> ids);
+
+    /**
+     * 用户ID查询店铺列表
+     */
+    List<StoreVo> selectByUserId(Long userId);
 }
diff --git a/smart-switch-service/src/main/java/com/ruoyi/ss/store/service/impl/StoreServiceImpl.java b/smart-switch-service/src/main/java/com/ruoyi/ss/store/service/impl/StoreServiceImpl.java
index f252f3a7..65e08bec 100644
--- a/smart-switch-service/src/main/java/com/ruoyi/ss/store/service/impl/StoreServiceImpl.java
+++ b/smart-switch-service/src/main/java/com/ruoyi/ss/store/service/impl/StoreServiceImpl.java
@@ -299,6 +299,16 @@ public class StoreServiceImpl implements IStoreService
         return selectSmStoreList(query);
     }
 
+    @Override
+    public List<StoreVo> selectByUserId(Long userId) {
+        if (userId == null) {
+            return Collections.emptyList();
+        }
+        StoreQuery query = new StoreQuery();
+        query.setUserId(userId);
+        return storeMapper.selectSmStoreList(query);
+    }
+
     /**
      * 通用查询数量
      *
diff --git a/smart-switch-service/src/main/java/com/ruoyi/ss/suit/mapper/SuitMapper.xml b/smart-switch-service/src/main/java/com/ruoyi/ss/suit/mapper/SuitMapper.xml
index b00c7873..4ada5af1 100644
--- a/smart-switch-service/src/main/java/com/ruoyi/ss/suit/mapper/SuitMapper.xml
+++ b/smart-switch-service/src/main/java/com/ruoyi/ss/suit/mapper/SuitMapper.xml
@@ -39,8 +39,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             store.name as store_name
         from sm_suit ss
             left join sm_device sd on sd.device_id = ss.device_id
-            left join sm_user su on su.user_id = sd.user_id
             left join sm_store store on store.store_id = sd.store_id
+            left join sm_user su on su.user_id = store.user_id
     </sql>
 
     <sql id="searchCondition">
diff --git a/smart-switch-service/src/main/java/com/ruoyi/ss/transactionBill/service/impl/TransactionBillServiceImpl.java b/smart-switch-service/src/main/java/com/ruoyi/ss/transactionBill/service/impl/TransactionBillServiceImpl.java
index 92c51b0f..33ba6092 100644
--- a/smart-switch-service/src/main/java/com/ruoyi/ss/transactionBill/service/impl/TransactionBillServiceImpl.java
+++ b/smart-switch-service/src/main/java/com/ruoyi/ss/transactionBill/service/impl/TransactionBillServiceImpl.java
@@ -545,7 +545,7 @@ public class TransactionBillServiceImpl implements TransactionBillService {
             ServiceUtil.assertion(TransactionBillDeviceRechargeStatus.SUCCESS.getStatus().equals(bill.getDeviceRechargeStatus()), "设备已充值成功,不允许再次充值");
         }
 
-        // 电表电量增加,四舍五入,保留1位小数
+        // 电表时长增加,四舍五入,保留1位小数
         boolean success = false;
         try {
             success = deviceService.addTime(bill.getDeviceId(), bill.getSuitTime());
diff --git a/smart-switch-service/src/main/java/com/ruoyi/task/device/deviceStartTask.java b/smart-switch-service/src/main/java/com/ruoyi/task/device/DeviceStartTask.java
similarity index 95%
rename from smart-switch-service/src/main/java/com/ruoyi/task/device/deviceStartTask.java
rename to smart-switch-service/src/main/java/com/ruoyi/task/device/DeviceStartTask.java
index 717ff252..4800e934 100644
--- a/smart-switch-service/src/main/java/com/ruoyi/task/device/deviceStartTask.java
+++ b/smart-switch-service/src/main/java/com/ruoyi/task/device/DeviceStartTask.java
@@ -16,7 +16,7 @@ import java.util.concurrent.Executors;
  */
 @Component
 @Slf4j
-public class deviceStartTask implements ApplicationRunner {
+public class DeviceStartTask implements ApplicationRunner {
 
     @Autowired
     private ISmMeterReadingRecordService smMeterReadingRecordService;
diff --git a/smart-switch-service/src/main/java/com/ruoyi/task/device/DeviceStatusTask.java b/smart-switch-service/src/main/java/com/ruoyi/task/device/DeviceStatusTask.java
new file mode 100644
index 00000000..c0b7c320
--- /dev/null
+++ b/smart-switch-service/src/main/java/com/ruoyi/task/device/DeviceStatusTask.java
@@ -0,0 +1,49 @@
+package com.ruoyi.task.device;
+
+import com.ruoyi.common.utils.CollectionUtils;
+import com.ruoyi.ss.device.domain.SmDeviceQuery;
+import com.ruoyi.ss.device.domain.enums.DeviceStatus;
+import com.ruoyi.ss.device.domain.vo.SmDeviceVo;
+import com.ruoyi.ss.device.service.ISmDeviceService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.ApplicationArguments;
+import org.springframework.boot.ApplicationRunner;
+import org.springframework.stereotype.Component;
+
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * @author wjh
+ * 2024/5/20
+ */
+@Component
+@Slf4j
+public class DeviceStatusTask implements ApplicationRunner {
+
+    @Autowired
+    private ISmDeviceService deviceService;
+
+    /**
+     * 项目启动时,查询所有正在使用的设备,并更新设备状态
+     * @param args
+     * @throws Exception
+     */
+    @Override
+    public void run(ApplicationArguments args) throws Exception {
+        log.info("项目启动,查询正在使用中的设备");
+        SmDeviceQuery query = new SmDeviceQuery();
+        query.setStatus(DeviceStatus.USING.getStatus());
+        List<SmDeviceVo> list = deviceService.selectSmDeviceList(query);
+        if (CollectionUtils.isEmptyElement(list)) {
+            log.info("没有正在使用中的设备");
+            return;
+        }
+
+        for (SmDeviceVo device : list) {
+            deviceService.freshStatus(device);
+        }
+
+    }
+}
diff --git a/smart-switch-web/src/main/java/com/ruoyi/web/controller/app/AppDeviceController.java b/smart-switch-web/src/main/java/com/ruoyi/web/controller/app/AppDeviceController.java
index 4386272f..b61ef602 100644
--- a/smart-switch-web/src/main/java/com/ruoyi/web/controller/app/AppDeviceController.java
+++ b/smart-switch-web/src/main/java/com/ruoyi/web/controller/app/AppDeviceController.java
@@ -102,7 +102,14 @@ public class AppDeviceController extends BaseController {
     @ApiOperation("绑定设备")
     @PutMapping("/bind")
     public AjaxResult bind(@RequestBody SmDevice device) {
-        return success(smDeviceService.bind(device.getStoreId(), device.getDeviceNo()));
+        if (StringUtils.isAllBlank(device.getDeviceNo(), device.getMac())) {
+            return error("设备编号和mac不能同时为空");
+        }
+        if (StringUtils.hasText(device.getDeviceNo())) {
+            return success(smDeviceService.bindBySn(device.getStoreId(), device.getDeviceNo()));
+        } else {
+            return success(smDeviceService.bindByMac(device.getStoreId(), device.getMac()));
+        }
     }
 
     @MchRequired
diff --git a/smart-switch-web/src/main/java/com/ruoyi/web/controller/app/AppStoreController.java b/smart-switch-web/src/main/java/com/ruoyi/web/controller/app/AppStoreController.java
index 7b01bc18..1929363a 100644
--- a/smart-switch-web/src/main/java/com/ruoyi/web/controller/app/AppStoreController.java
+++ b/smart-switch-web/src/main/java/com/ruoyi/web/controller/app/AppStoreController.java
@@ -65,7 +65,6 @@ public class AppStoreController extends BaseController {
      * @param store
      * @return
      */
-    @DataScope
     @MchRequired
     @ApiOperation("修改店铺信息")
     @PutMapping